<template>
  <div class="image-upload">
    <!--
      这里分为两段遍历，理由是：在编辑情况下要默认为组件添加默认数据，虽然说组件提供了 `add` 方法，
        但在编辑状态下，需要把 url 形式的图片转换成 File 之后才可以添加进去，略微麻烦。
        所以分两次遍历，一次遍历表单对象里的图片（直接用img标签展示，新上传的图片可以通过 blob 来赋值 src），第二次遍历组件里的 files
    -->
    <div
      class="file-item"
      v-for="(file, index) in value">
      <img
        :src="file.thumb || file.url"
        @click="preview(index)"
      />
      <van-icon
        name="clear"
        class="close"
        size="16px"
        @click="remove(index, true)"/>   <!-- 把图片从数组中删除 -->
    </div>
    <div
      :class="{'file-item': true, 'active': file.active, 'error': !!file.error}"
      v-for="(file, index) in files">  <!-- 加几个样式来控制 `上传中` 和 `上传失败` 的样式-->
      <img
        v-if="file.blob"
        :src="file.blob"
      />
      <div class="uploading-shade" v-show="!file.error && file.active">
        <p>{{ file.progress }} %</p>
        <p>正在上传</p>
      </div>
      <div class="error-shade" v-show="file.error !== 'compressing' && file.error">
        <p>上传失败</p>
      </div>
      <van-icon
        name="clear"
        class="close"
        size="16px"
        @click="remove(index)"
      />
    </div>
    <file-upload
    :style="{ position: !isDisabled ? 'relative' : 'absolute' }"
      ref="uploader"
      v-model="files"
      :multiple="false"
      :thread="1"
      :maximum="maximum"
      extensions="jpg,jpeg,gif,png,webp"
      accept="image/*"
      :name="id"
      :size="size || 0"
      :post-action="postAction"
      @input-file="inputFile"
      @input-filter="inputFilter"
    >
      <van-icon name="plus" size="36px" />
    </file-upload>
    </div>
</template>

<script>
  import uploader from 'vue-upload-component'
  import Compressor from 'compressorjs';
  import { ImagePreview } from 'vant';
  const postAction = process.env.VUE_APP_APP_URL + 'qywx-rest/qywx/cos/uploadImg'
  export default {
    name: 'ImageUpload',
    props: {
      value: Array, // 通过`.sync`来添加更新值的语法题，通过 this.$emit('update:value', this.value) 来更新
      maximum: {
        type: Number,
        default: 3
      },
      postAction: {
        type: String,
        default: 'https://sit.zooming-data.com/qywx-rest/qywx/cos/uploadImg'
      },
      id: {
        type: String,
        required: true
      }
    },
    data() {
      return {
        files: [], // 存放在组件的file对象
        size: 1024 * 1024 * 10,
        isDisabled: false
      }
    },
    watch: {
      value(val) {
        this.isDisabled = this.value.length === this.maximum
      }
    },
    components: {
      'file-upload': uploader
    },
    methods: {
      // 当 add, update, remove File 这些事件的时候会触发
      inputFile(newFile, oldFile) {
        // 上传完成
        console.log('newFile')
        console.log(newFile)
        console.log('oldFile')
        console.log(oldFile)
        if (newFile && oldFile && !newFile.active && oldFile.active) {
          console.log("上传成功")
          // 获得相应数据
          if (newFile.xhr && newFile.xhr.status === 200) {
            console.log("接口上传成功")
            newFile.response.data.thumb = newFile.thumb || newFile.blob // 把缩略图转移
            console.log(newFile.response.data)
            this.value.push(newFile.response.data) // 把 uploader 里的文件赋值给 value
            this.$refs.uploader.remove(newFile) // 删除当前文件对象
            this.$emit('update:value', this.value) // 更新值
          }
        }
        // 自动上传
        if (Boolean(newFile) !== Boolean(oldFile) || oldFile.error !== newFile.error) {
          console.log("上传1")
          if (!this.$refs.uploader.active) {
            console.log("上传2")
            this.$refs.uploader.active = true
          }
        }
      },
      // 文件过滤，可以通过 prevent 来阻止上传
      inputFilter(newFile, oldFile, prevent) {
        // 该状态是本地图片上传之前和服务器上传成功之后
        if (newFile && (!oldFile || newFile.file !== oldFile.file)) {
          // 自动压缩
          if (newFile.file && newFile.type.substr(0, 6) === 'image/') { // && this.autoCompress > 0 && this.autoCompress < newFile.size（小于一定尺寸就不压缩）
            newFile.error = 'compressing'
            let that = this
            new Compressor(newFile.file, {
              quality: 0.6,
              // convertSize: Infinity,
              convertSize: 5000000,
              // maxWidth: 1024,
              // maxHeight: 1024,
              success(file) {
                let URL = window.URL || window.webkitURL
                if (URL && URL.createObjectURL) {
                  newFile.blob = URL.createObjectURL(file)
                }
                console.log(file.size)
                // 缩略图
                newFile.thumb = ''
                if (newFile.blob && newFile.type.substr(0, 6) === 'image/') {
                  newFile.thumb = newFile.blob
                }
                // 更新 file
                that.$refs.uploader.update(newFile, {error: '', file, size: file.size, type: file.type})
              },
              error(err) {
                that.$refs.uploader.update(newFile, {error: err.message || 'compress'})
                console.log(err.message);
              },
            });
            console.log('123')
            // 压缩图片
            // const imageCompressor = new ImageCompressor(null, {
            //   quality: .5,
            //   convertSize: 5000000,
            //   maxWidth: 1024,
            //   maxHeight: 1024
            // })
            // imageCompressor.compress(newFile.file).then((file) => {
            //   console.log(file)
            //   // 创建 blob 字段 用于图片预览
            //   newFile.blob = ''
            //   let URL = window.URL || window.webkitURL
            //   if (URL && URL.createObjectURL) {
            //     newFile.blob = URL.createObjectURL(file)
            //   }
            //   // 缩略图
            //   newFile.thumb = ''
            //   if (newFile.blob && newFile.type.substr(0, 6) === 'image/') {
            //     newFile.thumb = newFile.blob
            //   }
            //   // 更新 file
            //   this.$refs.uploader.update(newFile, {error: '', file, size: file.size, type: file.type})
            // }).catch((err) => {
            //   this.$refs.uploader.update(newFile, {error: err.message || 'compress'})
            // })
          }
        }

      },
      remove(index, isValue) {
        if (isValue) {
          this.value.splice(index, 1)
          this.$emit('update:value', this.value)
        } else {
          this.$refs.uploader.remove(this.files[index])
        }
      },
      preview(index) {
        ImagePreview({
          images: this.value.map(item => (item.thumb || item.url)),
          startPosition: index
        });
      }
    }
  }
</script>

<style lang="less" scoped>

.image-upload {
  .file-item {
    width: 80px;
    height: 80px;
    border-radius: 6px;
    margin-right: 8px;
    margin-bottom: 8px;
    position: relative;
    overflow: hidden;
    float: left;

    .uploading-shade {
      height: 100%;
      width: 100%;
      background: #888;
      position: absolute;
      border-radius: 6px;
      top: 0;
      left: 0;
      opacity: 0.6;
      text-align: center;
      padding-top: 26px;
    }

    .error-shade {
      width: 100%;
      height: 100%;
      background: rgba(169, 140, 161, 0.6);
      color: #fff;
      font-weight: bold;
      text-align: center;
      position: absolute;
      border-radius: 6px;
      top: 0;
      left: 0;
      padding-top: 30px;
    }

    .close {
      position: absolute;
      top: 2px;
      right: 2px;
      color: #EA4D2E;
    }
  }

  .file-item:nth-child(4n) {
    margin-right: 0px;
  }

  .file-uploads-html5 {
    width: 80px;
    height: 80px;
    border-radius: 6px;
    // margin-right: 8px;
    margin-bottom: 8px;
    border: 1px dashed #9CA5B5;

    .van-icon-plus {
      color: #9CA5B5;
      padding-top: 22px;
    }
  }

  .file-uploads-disabled {
    opacity: 0.2;
  }

  img {
    // height: auto;
    object-fit: cover;
    width: 100%;
    height: 100%;
    border-radius: 6px;
  }
}

</style>
